﻿using System;
using System.Collections.Generic;
using System.Windows.Media;

namespace Gmantis.Controls.Chart
{
    public enum Palette
    {
        Default,
        Standard,
        Office,
        GrayScale,
        Apex,
        Aspect,
        Civic,
        Concourse,
        Equity,
        Flow,
        Foundry,
        Median,
        Metro,
        Module,
        Opulent,
        Oriel,
        Origin,
        Paper,
        Solstice,
        Technic,
        Trek,
        Urban,
        Verve
    }

    internal class StyleGenerator
    {
        // Fields
        private Palette _colorGen;
        private Brush[] _customBrushes;
        private List<ShapeStyle> _list = new List<ShapeStyle>();
        private List<ShapeStyle> _list2 = new List<ShapeStyle>();
        public Converter<Brush, Brush> CustomBrushConverter;

        // Methods
        private Brush GetCustomBrush(int i)
        {
            if (this.CustomBrushes == null)
            {
                return null;
            }
            Brush input = this.CustomBrushes[i % this.CustomBrushes.Length];
            if (this.CustomBrushConverter != null)
            {
                input = this.CustomBrushConverter(input);
            }
            return input;
        }

        public ShapeStyle GetStyle(int i)
        {
            if (i < this._list.Count)
            {
                return this._list[i];
            }
            return this.Next();
        }

        public ShapeStyle GetStyle2(int i)
        {
            if (i >= this._list2.Count)
            {
                this.Next();
            }
            return this._list2[i];
        }

        private static void InitStyle(ShapeStyle ss, Brush brush, bool dark)
        {
            ss.FillAuto = ss.Fill = brush;
            Color gray = Colors.Gray;
            SolidColorBrush brush2 = brush as SolidColorBrush;
            if (brush2 != null)
            {
                gray = brush2.Color;
            }
            else
            {
                GradientBrush brush3 = brush as GradientBrush;
                if (((brush3 != null) && (brush3.GradientStops != null)) && (brush3.GradientStops.Count > 0))
                {
                    gray = brush3.GradientStops[0].Color;
                }
            }
            Color color = dark ? ColorPalette.Darken(gray) : gray;
            ss.StrokeAuto = ss.Stroke = new SolidColorBrush(color);
        }

        private static void InitStyle(ShapeStyle ss, Color clr, bool dark)
        {
            SolidColorBrush fill = ss.Fill as SolidColorBrush;
            if (fill == null)
            {
                try
                {
                    ss.FillAuto = ss.Fill = new SolidColorBrush(clr);
                }
                catch
                {
                }
            }
            else
            {
                fill.Color = clr;
            }
            fill = ss.Stroke as SolidColorBrush;
            Color color = dark ? ColorPalette.Darken(clr) : clr;
            if (fill == null)
            {
                ss.StrokeAuto = ss.Stroke = new SolidColorBrush(color);
            }
            else
            {
                fill.Color = color;
            }
        }

        public ShapeStyle Next()
        {
            return this.Next(true);
        }

        public ShapeStyle Next(bool dark)
        {
            ShapeStyle style2;
            ShapeStyle ss = new ShapeStyle();
            if ((this.CustomBrushes != null) && (this._colorGen == Palette.Default))
            {
                InitStyle(ss, this.GetCustomBrush(this._list.Count), dark);
            }
            else
            {
                Palette colorGenTheme = (this._colorGen == Palette.Default) ? Palette.Apex : this._colorGen;
                Color clr = ColorPalette.GetOfficePalette(colorGenTheme).GetColor(this._list.Count);
                InitStyle(ss, clr, dark);
            }
            ss.DarkOutline = dark;
            ss.StrokeThickness = 2.0;
            this._list.Add(ss);
            style2 = new ShapeStyle
            {
                //FillAuto = style2.Fill = ss.FillAuto,
                //StrokeAuto = style2.Stroke = ss.StrokeAuto,
                StrokeThickness = 2.0
            };
            style2.FillAuto = style2.Fill = ss.FillAuto;
            style2.StrokeAuto = style2.Stroke = ss.StrokeAuto;
            this._list2.Add(style2);
            return ss;
        }

        public void Reset()
        {
            this._list.Clear();
            this._list2.Clear();
        }

        private void SetColors(Palette cg)
        {
            int count = this._list.Count;
            if (cg == Palette.Default)
            {
                if (this.CustomBrushes != null)
                {
                    for (int j = 0; j < count; j++)
                    {
                        Brush customBrush = this.GetCustomBrush(j);
                        InitStyle(this._list[j], customBrush, this._list[j].DarkOutline);
                        this.SyncStyle(j);
                    }
                    return;
                }
                cg = Palette.Apex;
            }
            for (int i = 0; i < count; i++)
            {
                Color clr = ColorPalette.GetOfficePalette(cg).GetColor(i);
                InitStyle(this._list[i], clr, this._list[i].DarkOutline);
                this.SyncStyle(i);
            }
        }

        private void SyncStyle(int i)
        {
            this._list2[i].Fill = this._list2[i].FillAuto = this._list[i].FillAuto;
            this._list2[i].Stroke = this._list2[i].StrokeAuto = this._list[i].StrokeAuto;
        }

        // Properties
        public Brush[] CustomBrushes
        {
            get
            {
                return this._customBrushes;
            }
            set
            {
                if (this._customBrushes != value)
                {
                    this._customBrushes = value;
                    if ((this._customBrushes != null) && (this.Palette == Palette.Default))
                    {
                        int count = this._list.Count;
                        for (int i = 0; i < count; i++)
                        {
                            Brush customBrush = this.GetCustomBrush(i);
                            InitStyle(this._list[i], customBrush, this._list[i].DarkOutline);
                            this.SyncStyle(i);
                        }
                    }
                    else
                    {
                        this.SetColors(this.Palette);
                    }
                }
            }
        }

        internal List<ShapeStyle> List
        {
            get
            {
                return this._list;
            }
        }

        internal List<ShapeStyle> List2
        {
            get
            {
                return this._list2;
            }
        }

        public Palette Palette
        {
            get
            {
                return this._colorGen;
            }
            set
            {
                if (this._colorGen != value)
                {
                    this._colorGen = value;
                    this.SetColors(this._colorGen);
                }
            }
        }
    }
}
